package ar.com.aterrizar.test.filtros;

import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import ar.com.aterrizar.asientos.Asiento;
import ar.com.aterrizar.asientos.AsientoOceanic;
import ar.com.aterrizar.entidades.Categoria;
import ar.com.aterrizar.entidades.Cliente;
import ar.com.aterrizar.entidades.TipoDeClaseAsiento;
import ar.com.aterrizar.entidades.TipoDeUbicacionAsiento;
import ar.com.aterrizar.filtrosBusqueda.FiltroObligatorio;
import ar.com.aterrizar.filtrosBusqueda.FiltroOpcional;
import ar.com.aterrizar.filtrosBusqueda.FiltroPorAsientosReservados;
import ar.com.aterrizar.filtrosBusqueda.FiltroPorClase;
import ar.com.aterrizar.filtrosBusqueda.FiltroPorPrecio;
import ar.com.aterrizar.filtrosBusqueda.FiltroPorUbicacion;

import com.google.common.collect.Iterables;

public class FiltrosOpcionalesOceanic {
	private List<Asiento> asientos = new ArrayList<Asiento>();
	Cliente cliente = new Cliente("Raul", "Fernandez", 15786664, Categoria.STANDARD, false);
	
	public FiltrosOpcionalesOceanic(){
		//Se crea todo la lista que sera filtrada multiples veces por cada test
		asientos.add(new AsientoOceanic("001", 1, "10/10/2012 10:00", "09/10/2012 09:00", "Madrid", "Buenos Aires", (float)1000, TipoDeClaseAsiento.TURISTA, TipoDeUbicacionAsiento.PASILLO, true));
		asientos.add(new AsientoOceanic("001", 2, "11/10/2012 10:00", "10/10/2012 09:00", "Madrid", "Buenos Aires", (float)1000, TipoDeClaseAsiento.TURISTA, TipoDeUbicacionAsiento.VENTANA, true));
		asientos.add(new AsientoOceanic("001", 3, "10/10/2012 10:00", "10/10/2012 09:00", "Madrid", "Buenos Aires", (float)2000, TipoDeClaseAsiento.EJECUTIVA, TipoDeUbicacionAsiento.PASILLO, false));
		asientos.add(new AsientoOceanic("001", 4, "11/10/2012 10:00", "11/10/2012 09:00", "Madrid", "Buenos Aires", (float)2000, TipoDeClaseAsiento.EJECUTIVA, TipoDeUbicacionAsiento.VENTANA, false));
		asientos.add(new AsientoOceanic("002", 5, "11/10/2012 10:00", "10/10/2012 09:00", "Paris", "Buenos Aires", (float)3000, TipoDeClaseAsiento.PRIMERACLASE, TipoDeUbicacionAsiento.CENTRO, false));
		asientos.add(new AsientoOceanic("002", 6, "11/10/2012 10:00", "10/10/2012 09:00", "Barcelona", "Buenos Aires", (float)3000, TipoDeClaseAsiento.TURISTA, TipoDeUbicacionAsiento.PASILLO, false));
		asientos.add(new AsientoOceanic("002", 7, "11/10/2012 10:00", "10/10/2012 09:00", "Barcelona", "Buenos Aires", (float)4000, TipoDeClaseAsiento.PRIMERACLASE, TipoDeUbicacionAsiento.PASILLO, false));//
		asientos.add(new AsientoOceanic("002", 8, "11/10/2012 10:00", "10/10/2012 09:00", "Barcelona", "Buenos Aires", (float)4000, TipoDeClaseAsiento.TURISTA, TipoDeUbicacionAsiento.PASILLO, false));
		asientos.add(new AsientoOceanic("002", 9, "11/10/2012 10:00", "10/10/2012 09:00", "Barcelona", "Buenos Aires", (float)5000, TipoDeClaseAsiento.EJECUTIVA, TipoDeUbicacionAsiento.VENTANA, false));
		asientos.add(new AsientoOceanic("002", 10, "11/10/2012 10:00", "10/10/2012 09:00", "Barcelona", "Buenos Aires", (float)5000, TipoDeClaseAsiento.EJECUTIVA, TipoDeUbicacionAsiento.PASILLO, false));
		asientos.add(new AsientoOceanic("002", 11, "10/10/2012 10:00", "10/10/2012 09:00", "Barcelona", "Buenos Aires", (float)6000, TipoDeClaseAsiento.PRIMERACLASE, TipoDeUbicacionAsiento.VENTANA, true));
		asientos.add(new AsientoOceanic("002", 12, "10/10/2012 10:00", "10/10/2012 09:00", "Barcelona", "Buenos Aires", (float)6000, TipoDeClaseAsiento.PRIMERACLASE, TipoDeUbicacionAsiento.CENTRO, true));
	}
	
	
	@Test
	public void testFiltroBasico() {	
		List<Asiento> asientos_esperados = new ArrayList<Asiento>();
		asientos_esperados.add(asientos.get(0));
		asientos_esperados.add(asientos.get(1));
		asientos_esperados.add(asientos.get(2));
		
		
		FiltroObligatorio filtroObligatorio = new FiltroObligatorio("Madrid","Buenos Aires","10/10/2012",this.cliente);
		Iterable<Asiento> asientos_filtrados = filtroObligatorio.filtrar(asientos);

		assertTrue(Iterables.elementsEqual(asientos_esperados, asientos_filtrados));
	}
	@Test
	public void testFiltroPorPrecio() {	
		List<Asiento> asientos_esperados = new ArrayList<Asiento>();
		asientos_esperados.add(asientos.get(0));
		asientos_esperados.add(asientos.get(1));
		
		

		FiltroObligatorio filtroObligatorio = new FiltroObligatorio("Madrid","Buenos Aires","10/10/2012",this.cliente);
		FiltroOpcional filtroPorPrecio = new FiltroPorPrecio(filtroObligatorio,this.cliente, (float)100, (float)1500);
		Iterable<Asiento> asientos_filtrados = filtroPorPrecio.filtrar(asientos);
		
		assertTrue(Iterables.elementsEqual(asientos_esperados, asientos_filtrados));
	}
	@Test
	public void testPorUbicacion() {
		List<Asiento> asientos_esperados = new ArrayList<Asiento>();
		asientos_esperados.add(asientos.get(5));
		asientos_esperados.add(asientos.get(6));
		asientos_esperados.add(asientos.get(7));
		asientos_esperados.add(asientos.get(9));
		
		
		FiltroObligatorio filtroObligatorio = new FiltroObligatorio("Barcelona","Buenos Aires","10/10/2012",this.cliente);
		FiltroOpcional filtroPorPrecio = new FiltroPorUbicacion(filtroObligatorio,TipoDeUbicacionAsiento.PASILLO);
		Iterable<Asiento> asientos_filtrados = filtroPorPrecio.filtrar(asientos);
		
		assertTrue(Iterables.elementsEqual(asientos_esperados, asientos_filtrados));
	}
	@Test
	public void testPorClase() {
		List<Asiento> asientos_esperados = new ArrayList<Asiento>();
		asientos_esperados.add(asientos.get(8));
		asientos_esperados.add(asientos.get(9));
		
		
		FiltroObligatorio filtro = new FiltroObligatorio("Barcelona","Buenos Aires","10/10/2012",this.cliente);
		FiltroPorClase filtroPorClase = new FiltroPorClase(filtro);
		filtroPorClase.addClase(TipoDeClaseAsiento.EJECUTIVA);
		Iterable<Asiento> asientos_filtrados = filtroPorClase.filtrar(asientos);
		
		assertTrue(Iterables.elementsEqual(asientos_esperados, asientos_filtrados));
	}
	@Test
	public void testPorClase2() {
		List<Asiento> asientos_esperados = new ArrayList<Asiento>();
		asientos_esperados.add(asientos.get(8));
		asientos_esperados.add(asientos.get(9));
		
		
		FiltroObligatorio filtro = new FiltroObligatorio("Barcelona","Buenos Aires","10/10/2012",this.cliente);
		FiltroPorClase filtroPorClase = new FiltroPorClase(filtro,TipoDeClaseAsiento.EJECUTIVA);
		Iterable<Asiento> asientos_filtrados = filtroPorClase.filtrar(asientos);
		
		assertTrue(Iterables.elementsEqual(asientos_esperados, asientos_filtrados));
	}
	@Test
	public void testPorClaseMultiplesClases() {
		List<Asiento> asientos_esperados = new ArrayList<Asiento>();
		asientos_esperados.add(asientos.get(6));
		asientos_esperados.add(asientos.get(8));
		asientos_esperados.add(asientos.get(9));
		asientos_esperados.add(asientos.get(10));
		asientos_esperados.add(asientos.get(11));
		
		
		FiltroObligatorio filtro = new FiltroObligatorio("Barcelona","Buenos Aires","10/10/2012",this.cliente);
		FiltroPorClase filtroPorClase = new FiltroPorClase(filtro,TipoDeClaseAsiento.EJECUTIVA);
		filtroPorClase.addClase(TipoDeClaseAsiento.PRIMERACLASE);
		Iterable<Asiento> asientos_filtrados = filtroPorClase.filtrar(asientos);
		
		assertTrue(Iterables.elementsEqual(asientos_esperados, asientos_filtrados));
	}
	@Test
	public void testPorClaseMultiplesClases2() {
		List<Asiento> asientos_esperados = new ArrayList<Asiento>();
		asientos_esperados.add(asientos.get(5));
		asientos_esperados.add(asientos.get(6));
		asientos_esperados.add(asientos.get(7));
		asientos_esperados.add(asientos.get(8));
		asientos_esperados.add(asientos.get(9));
		asientos_esperados.add(asientos.get(10));
		asientos_esperados.add(asientos.get(11));
		
		
		FiltroObligatorio filtro = new FiltroObligatorio("Barcelona","Buenos Aires","10/10/2012",this.cliente);
		FiltroPorClase filtroPorClase = new FiltroPorClase(filtro,TipoDeClaseAsiento.EJECUTIVA);
		filtroPorClase.addClase(TipoDeClaseAsiento.PRIMERACLASE);
		filtroPorClase.addClase(TipoDeClaseAsiento.TURISTA);
		Iterable<Asiento> asientos_filtrados = filtroPorClase.filtrar(asientos);
		
		assertTrue(Iterables.elementsEqual(asientos_esperados, asientos_filtrados));
	}
	@Test
	public void testPorAsientoReservado() {
		List<Asiento> asientos_esperados = new ArrayList<Asiento>();
		asientos_esperados.add(asientos.get(5));
		asientos_esperados.add(asientos.get(6));
		asientos_esperados.add(asientos.get(7));
		asientos_esperados.add(asientos.get(8));
		asientos_esperados.add(asientos.get(9));
		asientos_esperados.add(asientos.get(10));
		asientos_esperados.add(asientos.get(11));
		
		
		FiltroObligatorio filtro = new FiltroObligatorio("Barcelona","Buenos Aires","10/10/2012",this.cliente);
		FiltroPorAsientosReservados filtroPorAsientosReservados = new FiltroPorAsientosReservados(filtro);
		Iterable<Asiento> asientos_filtrados = filtroPorAsientosReservados.filtrar(asientos);
		
		assertTrue(Iterables.elementsEqual(asientos_esperados, asientos_filtrados));
	}
}
